﻿using System;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;

namespace mkv16
{
	/// <summary>
	/// Local console running on separate thread for interacting with mkv16.
	/// </summary>
    public class ConsoleProtocol : IProtocol
    {
        /// <summary>
        /// Displays a windows form console window
        /// </summary>
        protected ConsoleWindow console;

        /// <summary>
        /// Indicates whether the object is actively connected.
        /// </summary>
        protected bool connected;

        /// <summary>
        /// Identifier for the instance of this service.
        /// </summary>
        protected string id;

        /// <summary>
        /// The name of the system that invoked the message.
        /// </summary>
        protected string nickname;

        /// <summary>
        /// These message events report useful information about text input from the console.
        /// </summary>
        public event MessageEvent MessageReceived, MessageSendSuccess, MessageSendFail;
        /// <summary>
        /// These connection events report status of the console connection.
        /// </summary>
        public event ConnectionEvent ConnectionSuccess, ConnectionWarning, ConnectionFail;

        public void Connect(string service, string name)
        {
            id = "Console:" + service;
            nickname = name;
            connected = false;

            CreateConnection(service, name);
            start();
        }

        public void Disconnect()
        {
            console.Close();
        }

        public void Say(string domain, string recipient, string text)
        {
            var message = new Message(domain, nickname, text);

            try
            {
                console.WriteLine(String.Format("{0}: {1}", nickname, text));

                if(MessageSendSuccess != null)
                    MessageSendSuccess(this, message);
            }
            catch(Exception)
            {
                if(MessageSendFail != null)
                    MessageSendFail(this, message);
            }
        }

        protected void CreateConnection(string service, string name)
        {
            try
            {
                console = new ConsoleWindow();

                console.InputSent += new EventHandler(console_InputReceived);
                console.FormClosed += new System.Windows.Forms.FormClosedEventHandler(console_FormClosed);

                if (ConnectionSuccess != null)
                    ConnectionSuccess(this, "Console window created");
            }
            catch (Exception e)
            {
                connected = false;

                if (ConnectionFail != null)
                    ConnectionFail(this, "Could not create console window reason "+e.Message);
            }
        }

        void console_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e)
        {
            connected = false;
            if(ConnectionWarning != null)
                ConnectionWarning(this, "Console has been closed by user");
        }

        void console_InputReceived(object sender, EventArgs e)
        {
            var message = new Message("private", "keyboard", console.LastInput);

            if (MessageReceived != null)
                MessageReceived(this, message);
        }

        protected void start()
        {
            connected = true;
            Application.Run(console);
            console.Show();
        }

        public string ID
        {
            get { return id; }
        }
	}
}